package com.gitee.apanlh.util.base;

import com.gitee.apanlh.exp.CallRuntimeException;
import com.gitee.apanlh.util.func.FuncCall;
import com.gitee.apanlh.util.func.FuncExecute;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**	
 * 	equals整合方法
 * 	
 * 	@author Pan
 */
public class Eq {
	
	/**
	 * 	构造函数
	 * 
	 * 	@author Pan
	 */
	private Eq() {
		//	不允许外部实例
		super();
	}
	
	/**	
	 * 	字符串比较
	 * 	
	 * 	@author Pan
	 * 	@param 	s1	字符串1
	 * 	@param 	s2	字符串2
	 * 	@return	boolean
	 */
	public static boolean str(String s1, String s2) {
		return StringUtils.eq(s1, s2);
	}

	/**
	 * 	字符串与字符串缓冲比较
	 *
	 * 	@author Pan
	 * 	@param 	s1	字符串1
	 * 	@param 	s2	字符串2
	 * 	@return	boolean
	 */
	public static boolean str(String s1, StringBuilder s2) {
		return StringUtils.eq(s1, s2);
	}

	/**
	 * 	字符串与字符串缓冲比较
	 *
	 * 	@author Pan
	 * 	@param 	s1	字符串1
	 * 	@param 	s2	字符串2
	 * 	@return	boolean
	 */
	public static boolean str(String s1, StringBuffer s2) {
		return StringUtils.eq(s1, s2);
	}

	/**	
	 * 	字符串与字符比较
	 * 	
	 * 	@author Pan
	 * 	@param 	s1	字符串1
	 * 	@param 	c1	字符1
	 * 	@return	boolean
	 */
	public static boolean str(String s1, Character c1) {
		return StringUtils.eq(s1, c1);
	}
	
	/**	
	 * 	字符串比较
	 * 	<br>只要任意一个匹配返回true
	 * 
	 * 	@author Pan
	 * 	@param 	s1		字符串1
	 * 	@param 	strings	一个或多个字符串
	 * 	@return	boolean
	 */
	public static boolean strOr(String s1, String... strings) {
		return StringUtils.eqOr(s1, strings);
	}


	/**
	 * 	字符串比较
	 * 	<br>只要任意一个匹配返回true
	 *
	 * 	@author Pan
	 * 	@param 	s1		字符串1
	 * 	@param 	list	一个或多个字符串
	 * 	@return	boolean
	 */
	public static boolean strOr(String s1, List<String> list) {
		return StringUtils.eqOr(s1, list);
	}

	/**
	 * 	字符串与枚举比较
	 * 	<br>只要任意一个匹配返回true
	 * 
	 * 	@author Pan
	 * 	@param 	s1		字符串
	 * 	@param 	es		一个或多个枚举
	 * 	@return	boolean
	 */
	public static boolean strOr(String s1, Enum<?>... es) {
		return StringUtils.eqOr(s1, es);
	}

	/**	
	 * 	类比较
	 * 	
	 * 	@author Pan
	 * 	@param 	c1	类1
	 * 	@param 	c2	类2
	 * 	@return	boolean
	 */
	public static boolean classes(Class<?> c1, Class<?> c2) {
		return ObjectUtils.eq(c1, c2);
	}
	
	/**	
	 * 	类比较
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>	  	数据类型
	 * 	@param 	obj1	值1
	 * 	@param 	obj2	值2
	 * 	@return	boolean
	 */
	public static <T> boolean object(T obj1, T obj2) {
		return ObjectUtils.eq(obj1, obj2);
	}
	
	/**	
	 * 	对象值比较 
	 *	包含匹配模式
	 *	传递匹配值其中包含匹配值obj1返回true
	 *
	 * 	@author Pan
	 * 	@param 	<T>	  数据类型
	 * 	@param 	o1	  值1
	 * 	@param 	o2    值2（一个或多个值）
	 * 	@return	boolean
	 */
	public static <T> boolean objectOr(T o1, T... o2) {
		return ObjectUtils.eqOr(o1, o2);
	}
	

	/**
	 * 	比较两个集合是否一致
	 * 	<br>包含模式
	 * 	<br>验证是否全包含元素
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>	  数据类型
	 * 	@param  list	集合1
	 * 	@param  list2	集合2	
	 * 	@return	boolean
	 */
	public static <T> boolean collection(Collection<T> list, Collection<T> list2) {
		return CollUtils.eq(list, list2);
	}
	
	/**
	 * 	比较两个集合是否一致
	 * 	<br>全匹配模式
	 * 	<br>严格验证顺序，值
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>	  数据类型
	 * 	@param  list	集合1
	 * 	@param  list2	集合2
	 * 	@return	boolean
	 */
	public static <T> boolean collectionByOrder(Collection<T> list, Collection<T> list2) {
		return CollUtils.eqByOrder(list, list2);
	}
	
	/**	
	 * 	比较两者Map
	 * 	<br>其中只比较Map中的value值
	 * 	<br>不严格限制顺序
	 * 
	 * 	@author Pan
	 * 	@param 	<K>	  	键类型
	 * 	@param 	<V>	  	值类型
	 * 	@param 	map		Map1
	 * 	@param 	map2	Map2
	 * 	@return	boolean
	 */
	public static <K, V> boolean mapValue(Map<K, V> map, Map<K, V> map2) {
		return MapUtils.eqByValue(map, map2);
	}
	
	/**	
	 * 	比较两者Map
	 * 	<br>value匹配模式(比较Map中的value值)
	 * 	<br>不严格限制顺序
	 * 
	 * 	@author Pan
	 *  @param  <K>     键类型
	 * 	@param  <V>     值类型
	 * 	@param 	map		Map1
	 * 	@param 	map2	Map2
	 * 	@return	boolean
	 */
	public static <K, V> boolean mapByKeyValue(Map<K, V> map, Map<K, V> map2) {
		return MapUtils.eqByKeyValue(map, map2);
	}
	
	/**	
	 * 	比较两者Map
	 * 	<br>其中比较规则Key+Value值
	 * 	<br>严格要求按照顺序比较
	 * 	
	 * 	@author Pan
	 *  @param  <K>     键类型
	 * 	@param  <V>     值类型
	 * 	@param 	map		Map1
	 * 	@param 	map2	Map2
	 * 	@return	boolean
	 */
	public static <K, V> boolean mapByOrder(Map<K, V> map, Map<K, V> map2) {
		return MapUtils.eqByOrder(map, map2);
	}
	
	 /**	
     * 	对象数组比较
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
	  * @param 	<T>	  	数据类型
     * 	@param 	o1		数组1
     * 	@param 	o2		数组2
     * 	@return	boolean
     */
	public static <T> boolean array(T[] o1, T[] o2) {
		return ArrayUtils.eq(o1, o2);
	}

	/**	
	 * 	short数组比较
     * 	<br>对比两者short[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源short[]
     * 	@param 	a2	目标short[]
     * 	@return	boolean
     */
    public static boolean array(short[] a1, short[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }

	/**	
	 * 	int数组比较
     * 	<br>对比两者int[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源int[]
     * 	@param 	a2	目标int[]
     * 	@return	boolean
     */
    public static boolean array(int[] a1, int[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }

	/**	
	 * 	long数组比较
     * 	<br>对比两者long[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源long[]
     * 	@param 	a2	目标long[]
     * 	@return	boolean
     */
    public static boolean array(long[] a1, long[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }
    
	/**	
	 * 	float数组比较
     * 	<br>对比两者float[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源float[]
     * 	@param 	a2	目标float[]
     * 	@return	boolean
     */
    public static boolean array(float[] a1, float[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }
    
	/**	
	 * 	double数组比较
     * 	<br>对比两者double[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源double[]
     * 	@param 	a2	目标double[]
     * 	@return	boolean
     */
    public static boolean array(double[] a1, double[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }

	/**	
	 * 	char数组比较
     * 	<br>对比两者char[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源char[]
     * 	@param 	a2	目标char[]
     * 	@return	boolean
     */
    public static boolean array(char[] a1, char[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }

	/**	
	 * 	boolean数组比较
     * 	<br>对比两者boolean[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	a1	来源boolean[]
     * 	@param 	a2	目标boolean[]
     * 	@return	boolean
     */
    public static boolean array(boolean[] a1, boolean[] a2) {
    	return ArrayUtils.eq(a1, a2);
    }
    
	/**	
	 * 	字节数组比较
     * 	<br>对比两者byte[]是否一致
     * 	<br>两个数组均为为null返回false
     * 
     * 	@author Pan
     * 	@param 	b1	来源byte[]
     * 	@param 	b2	目标byte[]
     * 	@return	boolean
     */
    public static boolean array(byte[] b1, byte[] b2) {
    	return ArrayUtils.eq(b1, b2);
    }
    
    /**
     * 	枚举比较
     * 	
     * 	@author Pan
     *  @param 	e1	枚举1
     * 	@param 	e2	枚举2
     * 	@return	boolean
     */
    public static boolean enums(Enum<?> e1, Enum<?> e2) {
    	return e1.equals(e2);
    }
	
	/**	
	 * 	枚举与字符串比较
	 * 	<br>注意:是根据枚举的name方法进行比较,使用时请注意重写name方法
	 *
	 * 	@author Pan
	 * 	@param 	e	枚举1
	 * 	@param 	s1	字符串2
	 * 	@return	boolean
	 */
	public static boolean enums(Enum<?> e, String s1) {
		if (s1 == null) {
			return false;
		}
		return e.name().equals(s1);
	}

    /**
     * 	枚举比较
     * 	包含匹配模式
	 *	传递匹配值其中包含匹配值任意一个返回true
	 *
     * 	@author Pan
     *  @param 	e1	枚举1
     * 	@param 	es	一个或多个枚举
     * 	@return	boolean
     */
    public static boolean enumsOr(Enum<?> e1, Enum<?>... es) {
		for (int i = 0; i < es.length; i++) {
			if (enums(e1, es[i])) {
				return true;
			}
		}
		return false;
    }
    
    /**
     * 	枚举比较
     * 	<br>匹配所有才返回true
     * 
     * 	@author Pan
     *  @param 	e1	枚举1
     * 	@param 	es	一个或多个枚举
     * 	@return	boolean
     */
    public static boolean enumsAnd(Enum<?> e1, Enum<?>... es) {
    	for (int i = 0; i < es.length; i++) {
			if (!enums(e1, es[i])) {
				return false;
			}
		}
		return true;
    }

	/**
	 *	比较值，如果ture执行回调
	 *
	 * 	@author Pan
	 * 	@param 	<T>		  	值类型
	 * 	@param 	value	  	值
	 * 	@param 	eqValue	   	比较值
	 * 	@param 	callValue	回调值
	 * 	@return	V
	 */
	public static <T> T call(T value, T eqValue, T callValue) {
		return ChooseEq.autoEq(value, eqValue) ? callValue : null;
	}

	/**
	 *	比较值，如果ture执行回调
	 *  <br>有返回值
	 *
	 * 	@author Pan
	 * 	@param 	<T>		  	值类型
	 * 	@param 	value	  	值
	 * 	@param 	eqValue	   	比较值
	 * 	@param 	call		回调函数
	 * 	@return	V
	 */
	public static <T> T call(T value, T eqValue, FuncCall<T> call) {
		try {
			return ChooseEq.autoEq(value, eqValue) ? call.call() : null;
		} catch (Exception e) {
			throw new CallRuntimeException(e.getMessage(), e);
		}
	}

	/**
	 *	比较值，如果ture执行回调
	 *  <br>无返回值
	 *
	 * 	@author Pan
	 * 	@param 	<T>		  	值类型
	 * 	@param 	value	  	值
	 * 	@param 	eqValue	   	比较值
	 * 	@param 	execute		回调函数
	 */
	public static <T> void call(T value, T eqValue, FuncExecute execute) {
		if (ChooseEq.autoEq(value, eqValue)) {
			execute.execute();
		}
	}

	/**
	 *	构建值匹配器
	 *	<br>默认单匹配值模式
	 *
	 * 	@author Pan
	 * 	@param 	<T>		  	值类型
	 * 	@param 	<R>		  	返回类型
	 * 	@return	ChooseEq
	 */
	public static <T, R> ChooseEq<T, R> matcher() {
		return ChooseEq.create();
	}

	/**
	 *	构建值匹配器
	 *	<br>自定义匹配值模式
	 *
	 * 	@author Pan
	 * 	@param 	<T>		  	值类型
	 * 	@param 	<R>		  	返回类型
	 * 	@param 	multiMode 	true多匹配模式,false单匹配模式
	 * 	@return	ChooseEq
	 */
	public static <T, R> ChooseEq<T, R> matcher(boolean multiMode) {
		return ChooseEq.create();
	}
}
